import ServiceExtensionContext from "D:/Work/HuaweiOHOS_SDK/OpenHarmonySDK_2022.12.07_fixed/9/ets/api/application/ServiceExtensionContext";
import RemoteDeviceModel from '../Distribute/remotedevicemodel';
import { KvStoreModel } from '../Distribute/kvstoremodel';

const TAG: string = 'BtConnector[Distribute]'

let kvStoreModel = new KvStoreModel();
let remoteDeviceModel = new RemoteDeviceModel()
let timerId = 0

export class Distribute {
public tmpFlags = 0
    context: ServiceExtensionContext = null
    isDistributed = false
    deviceList = []
    selectedIndex = 0
    onMessageReceivedListener: (s:string) => void = null
    onConnectionFinished: (boolean)=> void

    constructor(context: ServiceExtensionContext){
        this.context = context
    }

    init(onMessageReceivedListener: (s:string) => void, onConnectionFinished: (boolean)=> void) {
        this.onMessageReceivedListener = onMessageReceivedListener
        this.onConnectionFinished = onConnectionFinished
        console.log(`${TAG} init start`);
        //++++++++++this.grantPermission()
        this.initKVManager();
        console.log(`${TAG} init end`);
    }

    /*grantPermission() {
        console.info(`${TAG} grantPermission`)
        this.context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) {
            console.log(`${TAG} grantPermission,requestPermissionsFromUser,result.requestCode=${result}`)
        })
    }//*/

    onHide() {
        if (remoteDeviceModel === undefined) {
            return
        }
        remoteDeviceModel.unregisterDeviceListCallback();
        if (this.isDistributed && kvStoreModel != null) {
            this.stopDataListener();
            this.isDistributed = false;
        }
        clearInterval(timerId)
        kvStoreModel = null
        remoteDeviceModel = undefined
    }

    initKVManager() {
        console.log(`${TAG} initKVManager start`);
        if (kvStoreModel == undefined || kvStoreModel == null) {
            console.log(`${TAG} kvStoreModel absent. create new kvStoreModel`);
            kvStoreModel = new KvStoreModel()
        }
        kvStoreModel.setOnMessageReceivedListener('expression', (value) => {
            this.Listener(value)
        });
        console.log(`${TAG} initKVManager end`);
    }

    Listener(value) {
        if (this.onMessageReceivedListener != null) {
            //console.log(`${TAG} data changed:` + value);
            this.onMessageReceivedListener(value)
        }
        else {
            console.log(`${TAG} data changed:` + value + ' no callback');
        }
    }

    stopDataListener() {
        console.log(`${TAG} stopDataListener`);
        if (kvStoreModel === null || kvStoreModel === undefined) {
            return
        }
        kvStoreModel.off()
    }
    // *****************************************************************************************************************
    connect() {
        console.info(`${TAG} connect start`)
        if (this.isDistributed) {
            this.ConnectionFinished(this.isDistributed)
            console.warn(`${TAG} Connection is already completed`)
            return
        }
        setTimeout(()=>{
            this.deviceList = [];
            if (remoteDeviceModel === undefined) {
                remoteDeviceModel = new RemoteDeviceModel()
            }
            console.log(`${TAG} registerDeviceListCallback on remote device updated, count=`
            + remoteDeviceModel.deviceList.length)
            remoteDeviceModel.registerDeviceListCallback(() => {
                let list = []
                list.push({
                    deviceId: '0',
                    deviceName: 'Local device',
                    deviceType: 0,
                    networkId: '',
                    checked: this.selectedIndex === 0
                });
                let tempList = remoteDeviceModel.discoverList.length > 0 ? remoteDeviceModel.discoverList : remoteDeviceModel.deviceList;
                for (let i = 0; i < tempList.length; i++) {
                    console.log(`${TAG} device ` + i + '/' + tempList.length
                    + ' deviceId=' + tempList[i].deviceId + ' deviceName=' + tempList[i].deviceName
                    + ' deviceType=' + tempList[i].deviceType);
                    list.push({
                        deviceId: tempList[i].deviceId,
                        deviceName: tempList[i].deviceName,
                        deviceType: tempList[i].deviceType,
                        networkId: tempList[i].networkId,
                        checked: this.selectedIndex === (i + 1)
                    });
                }
                this.deviceList = list;
                for (let i = 0; i < this.deviceList.length; i++) {
                    console.log(`${TAG} Device[${i}] ${this.deviceList[i].deviceName}`)
                }
            });
        },200)

        setTimeout(()=>{
            if (this.deviceList.length > 1) {
                console.log(`${TAG} Connecting to ${this.deviceList[1].deviceName}`)
                setTimeout(()=>{
                    this.connectToDevice(this.deviceList[1])
                },100)
            }
            else {
                console.log(`${TAG} NO DEVICES FOUND`)
                this.cancelConnect()
                this.ConnectionFinished(false)
            }
        },400)
    }

    cancelConnect() {
        if (remoteDeviceModel === undefined) {
            return;
        }
        remoteDeviceModel.unregisterDeviceListCallback();
    }

    connectToDevice(item) {
        let index = this.deviceList.indexOf(item);
        console.log(`${TAG} select index:` + index);
        console.log(`${TAG} select selectedIndex:` + this.selectedIndex);
        if (index === this.selectedIndex) {
            console.log(`${TAG} index === this.selectedIndex`);
            return;
        }
        this.selectedIndex = index;
        if (index === 0) {
            console.log(`${TAG} stop ability`);
            this.dataTransmit('expression', 'exit');
            this.isDistributed = false;
            this.stopDataListener();
            this.clearSelectState();
            return;
        }
        for (var i = 0; i < remoteDeviceModel.discoverList.length; i++) {
            console.log(`${TAG} device[${i}]:` + JSON.stringify(this.deviceList[i]));
        }
        console.log(`${TAG} start ability ...... ${remoteDeviceModel.tmpCounter}`);
        if (remoteDeviceModel === undefined || remoteDeviceModel.discoverList.length <= 0) {
            console.log(`${TAG} continue device:` + JSON.stringify(this.deviceList));
            this.startAbility(this.deviceList[index].deviceId);
            this.tmpFlags |= 16
            this.clearSelectState();
            return;
        }
        console.log(`${TAG} start ability1, needAuth`);
        remoteDeviceModel.authenticateDevice(this.deviceList[index], () => {
            console.log(`${TAG} auth and online finished`);
            this.ConnectionFinished(false)
            return
            /*setTimeout(()=> {
                this.startAbility(this.deviceList[index].deviceId);
            }, 500)*/
        });
        this.clearSelectState();
        console.log(`${TAG} start ability end....`);
    }

    dataTransmit(key, value) {
        //console.log(`${TAG} dataTransmit isDistributed = ` + this.isDistributed);
        if (this.isDistributed && kvStoreModel != null) {
            kvStoreModel.put(key, value);
        }
    }

    clearSelectState() {
        this.deviceList = [];
    }

    async startAbility(deviceId) {
        console.log(`${TAG} startAbility deviceId:` + deviceId);
        if (deviceId === 0) {
            this.tmpFlags |= 2
            return
        }
        this.tmpFlags |= 1

        try {
            await this.context.startAbility({
                    deviceId: deviceId,
                    bundleName: 'ohos.samples.distributedcalc',
                    abilityName: 'ohos.samples.distributedcalc.MainAbility',
                    //parameters: {
                    //    isFA: 'FA' // isFA - value, 'FA' - key
                    //}
            })
        } catch (err) {
            console.log(`${TAG} startAbility err is ${JSON.stringify(err)}`)
            this.tmpFlags |= 4
            this.ConnectionFinished(true)
        }
        this.tmpFlags |= 8
        console.log(`${TAG} startAbility end`);
    }

    ConnectionFinished(isDistributed: boolean) {
        console.info(`${TAG} conState ${this.isDistributed}->${isDistributed}`)
        this.isDistributed = isDistributed
        if (this.onConnectionFinished != null) {
            this.onConnectionFinished(isDistributed)
        }
    }
}